﻿using System;
using System.Linq;
using System.Threading.Tasks;
using Yz.Base;

namespace Yz.Cache
{
    public sealed class CacheAppUitility : BaseCacheUitility, ICacheUitility
    {
        #region 从缓存中获得数据
        /// <summary>
        /// 具体执行缓存委托或更新缓存
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="Func">委托方法</param>
        /// <param name="args">至少有2个参数（从右往左（从后往前），1：是否去更新缓存，2：CacheDbTime 对象（包含时间和数据库索引）</param>
        /// <returns>List<T></returns>
        protected override ReturnList<T> GetDataListFromCache<T>(Delegate func, object[] args)
        {
            ReturnList<T> itemList = new ReturnList<T>();
            if (args.Length < 2)
            {
                return itemList;
            }
            var cachePara = base.GetCachePara(func, args);
            string cacheKey = GetCacheKey(cachePara.Key);
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            object obj = null;
            if (cachePara.Update || !cachePrivoder.Contains(cacheKey, out obj))//为了更新缓存
            {
                itemList = (ReturnList<T>)func.DynamicInvoke(args.Take(args.Length - 2).ToArray());
                cachePrivoder.Set(cacheKey, itemList, cachePara.Expiry);
            }
            else
            {
                itemList = (ReturnList<T>)cachePrivoder.Get(cacheKey);
            }
            return itemList;
        }
        /// <summary>
        /// 具体执行缓存委托或更新缓存
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="Func">委托方法</param>
        /// <param name="args">至少有2个参数（从右往左（从后往前），1：是否去更新缓存，2：CacheDbTime 对象（包含时间和数据库索引）</param>
        /// <returns>List<T></returns>
        protected override async Task<ReturnList<T>> GetDataListFromCacheAsync<T>(Delegate func, object[] args)
        {
            ReturnList<T> itemList = new ReturnList<T>();
            if (args.Length < 2)
            {
                return itemList;
            }
            var cachePara = base.GetCachePara(func, args);
            string cacheKey = GetCacheKey(cachePara.Key);
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            object obj = null;
            if (cachePara.Update || !cachePrivoder.Contains(cacheKey, out obj))//为了更新缓存
            {
                itemList = await (Task<ReturnList<T>>)func.DynamicInvoke(args.Take(args.Length - 2).ToArray());
                await cachePrivoder.SetAsync(cacheKey, itemList, cachePara.Expiry);
            }
            else
            {
                itemList = (ReturnList<T>)await cachePrivoder.GetAsync(cacheKey);
            }
            return itemList;
        }
        /// <summary>
        /// 具体执行缓存委托或更新缓存
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="func">委托方法</param>
        /// <param name="args">至少有2个参数（从右往左（从后往前），1：是否去更新缓存，2：CacheDbTime 对象（包含时间和数据库索引）</param>
        /// <returns>T</returns>
        protected override T GetDataFromCache<T>(Delegate func, object[] args)
        {
            T item = default(T);
            if (args.Length < 2)
            {
                return item;
            }
            var cachePara = base.GetCachePara(func, args);
            string cacheKey = GetCacheKey(cachePara.Key);
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            object obj = null;
            if (cachePara.Update || !cachePrivoder.Contains(cacheKey, out obj))//为了更新缓存
            {
                item = (T)func.DynamicInvoke(args.Take(args.Length - 2).ToArray());
                cachePrivoder.Set(cacheKey, item, cachePara.Expiry);
            }
            else
            {
                item = (T)cachePrivoder.Get(cacheKey);
            }
            return item;
        }
        /// <summary>
        /// 具体执行缓存委托或更新缓存
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="func">委托方法</param>
        /// <param name="args">至少有2个参数（从右往左（从后往前），1：是否去更新缓存，2：CacheDbTime 对象（包含时间和数据库索引）</param>
        /// <returns>Task<T></returns>
        protected override async Task<T> GetDataFromCacheAsync<T>(Delegate func, object[] args)
        {
            T item = default(T);
            if (args.Length < 2)
            {
                return item;
            }
            var cachePara = base.GetCachePara(func, args);
            string cacheKey = GetCacheKey(cachePara.Key);
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            object obj = null;
            if (cachePara.Update || cachePrivoder.Contains(cacheKey, out obj) == false)//为了更新缓存
            {
                item = await (Task<T>)func.DynamicInvoke(args.Take(args.Length - 2).ToArray());
                await cachePrivoder.SetAsync(cacheKey, item, cachePara.Expiry);
            }
            else
            {
                item = (T)await cachePrivoder.GetAsync(cacheKey);
            }
            return item;
        }
        #endregion 从缓存中获取数据（有委托）

        #region 设置缓存
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cachePara"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetCache<T>(ParaCache cachePara, T value)
        {
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            string cacheKey = GetCacheKey(cachePara.Key);
            cachePrivoder.Set(cacheKey, value, cachePara.Expiry);
            return true;
        }
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cachePara"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> SetCacheAsync<T>(ParaCache cachePara, T value)
        {
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            string cacheKey = GetCacheKey(cachePara.Key);
            await cachePrivoder.SetAsync(cacheKey, value, cachePara.Expiry);
            return true;
        }

        #endregion

        #region 查询缓存
        /// <summary>
        /// 获得缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cachePara"></param>
        /// <returns></returns>
        public T GetCache<T>(BaseParaCache cachePara)
        {
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            string cacheKey = GetCacheKey(cachePara.Key);
            return cachePrivoder.Get<T>(cacheKey);
        }
        /// <summary>
        /// 获得缓存
        /// </summary>
        /// <param name="cachePara"></param>
        /// <returns></returns>
        public string GetCache(BaseParaCache cachePara)
        {
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            string cacheKey = GetCacheKey(cachePara.Key);
            return cachePrivoder.Get<string>(cacheKey);
        }
        /// <summary>
        ///获得缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cachePara"></param>
        /// <returns></returns>
        public async Task<T> GetCacheAsync<T>(BaseParaCache cachePara)
        {
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            string cacheKey = GetCacheKey(cachePara.Key);
            return await cachePrivoder.GetAsync<T>(cacheKey);
        }
        /// <summary>
        /// 获得缓存
        /// </summary>
        /// <param name="cachePara"></param>
        /// <returns></returns>
        public async Task<string> GetCacheAsync(BaseParaCache cachePara)
        {
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            string cacheKey = GetCacheKey(cachePara.Key);
            return await cachePrivoder.GetAsync<string>(cacheKey);
        }

        #endregion 

        #region 清空缓存

        /// <summary>
        /// 删除缓存（不支持模糊匹配）
        /// </summary>
        /// <param name="cacheKey">key值</param>
        /// <returns></returns>
        public bool DeleteCache(string cacheKey, int dbNum = 0)
        {
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            cacheKey = GetCacheKey(cacheKey);
            cachePrivoder.Delete(cacheKey);
            return true;
        }
        /// <summary>
        /// 删除缓存（不支持模糊匹配）
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <param name="dbNum"></param>
        /// <returns></returns>
        public async Task<bool> DeleteCacheAsync(string cacheKey, int dbNum = 0)
        {
            CacheAppProvider cachePrivoder = new CacheAppProvider();
            cacheKey = GetCacheKey(cacheKey);
            await cachePrivoder.DeleteAsync(cacheKey);
            return true;
        }

        #endregion 清空缓存
    }
}
